package com.lyy;

import lombok.SneakyThrows;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

/** @author JoeZhou */
public class MyBatisUtil {

    /**开发工厂属性: 饱汉单例不赋初值*/
    private static volatile SqlSessionFactory factory;

    /**
     * 获取单例的session工厂实例
     *
     * @param resource 主配文件的classpath位置，字符串
     * @return 单例的session工厂实例
     */
    @SneakyThrows
    public static SqlSessionFactory getFactory(String resource) {
        // 双重检查锁: DCL第1个if检查用于避免后续线程的加锁接锁开销
        if (factory == null) {
            // 双重检查锁: DCL锁用于避免线程争抢，毁坏单例效果
            synchronized (MyBatisUtil.class) {
                // 双重检查锁: DCL第2个if检查用于使用饱汉单例模式构建工厂实例
                if (factory == null) {
                    // 返回主配的字节流对象，创建Session工厂需要
                    InputStream inputStream = Resources.getResourceAsStream(resource);
                    // 创建Session工厂
                    factory = new SqlSessionFactoryBuilder().build(inputStream);
                }
            }
        }
        // 返回Session工厂
        return factory;
    }
}